class Vue { 
  constructor(options) {
    // 1. 通过属性保存选项的数据
    this.$options = options
    const { el, data } = options
    this.$data = data || {}
    // 如果是选择器， 则获取DOM元素
    this.$el = typeof el === 'string' ? document.querySelector(el) : el
    // 2. 把data中的成员转换成getter和setter，注入到vue实例中
    this._proxyData(data)
    // 3. 调用observer对象，监听数据的变化
    new Observer(data)
    // 4. 调用compiler对象，解析指令和差值表达式
    new Compiler(this)
  }
  /**
   * 代理数据, 把data里面的属性转换成getter, setter
   * @param {*} data 
   */
  _proxyData(data) {
    // 遍历data中的所有属性
    Object.keys(data).forEach(key => { 
      // 把data的属性注入到vue实例中
      Object.defineProperty(this, key, {
        enumerable: true, // 可枚举
        configurable: true, // 可配置,
        get() { 
          return data[key]
        },
        set(newValue) { 
          if (data[key] === newValue) return
          data[key] = newValue
        }
      })
    })
   }
}